<template>
  <div class="homeapp">
    <div class="my-apps">
      <div class="head">
        <span class="title">我的应用：</span>
        <span class="tip">（拖动调整顺序）</span>
      </div>
      <div
        ref="myApp"
        class="list"
        :style="{
          height:
            Math.ceil(showItems.length / howColsInOneRow) * 106 - 10 + 'px'
        }"
      >
        <div
          v-for="(showItem, showIndex) in showItems"
          class="item"
          ref="showItems"
          :style="{
            left: showItem.left + 'px',
            top: showItem.top + 'px',
            zIndex: showItem.zIndex
          }"
          @mousedown="showItemMousedown($event, showIndex)"
          :key="showIndex"
        >
          <img
            @mousedown="ev => ev.preventDefault()"
            width="55"
            height="48"
            :src="showItem.icon"
            alt="图标"
          />
          <p>{{ showItem.name }}</p>
          <span @click="removeMyApp(showIndex)" class="remove"
            ><span></span
          ></span>
        </div>
      </div>
    </div>
    <div class="other-app">
      <div class="head">
        <span class="title">所有应用：</span>
      </div>
      <div class="list">
        <div
          v-for="(otherItem, otherIndex) in otherItems"
          class="item"
          :key="otherIndex"
        >
          <img :src="otherItem.icon" alt="图标" />
          <p>{{ otherItem.name }}</p>
          <span @click="addOtherApp(otherIndex)" class="add">
            <span class="hor"></span>
            <span class="ver"></span>
          </span>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import systemHomeapp from "@/const/system_homeshowapp.json";
import systemHomeOtherApp from "@/const/system_homeotherapp.json";
export default {
  data() {
    return {
      howColsInOneRow: 0,
      showItems: [],
      otherItems: systemHomeOtherApp
    };
  },
  mounted() {
    this.adjust();

    window.addEventListener("resize", this.adjust);

    this.$nextTick(() => {
      systemHomeapp.forEach((item, index) => {
        item.top = this.calcTop(index);
        item.left = this.calcLeft(index);
        item.zIndex = 0;
      });
      this.showItems = systemHomeapp;
    });
  },
  methods: {
    removeMyApp(i) {
      this.otherItems.push(this.showItems[i]);
      this.showItems.splice(i, 1);
      this.adjust();
    },
    addOtherApp(i) {
      this.showItems.push(this.otherItems[i]);
      this.otherItems.splice(i, 1);
      this.adjust();
    },
    calcLeft(index) {
      const rows = this.howColsInOneRow;
      return (index - Math.floor(index / rows) * rows) * 110;
    },
    calcTop(index) {
      return Math.floor(index / this.howColsInOneRow) * 106;
    },
    showItemMousedown(ev, index) {
      var vm = this;
      var curElem = ev.target;
      var isRemoveChild = false;
      var myApp = vm.$refs.myApp;
      var dragElems = vm.$refs.showItems;
      var dragItem = vm.showItems[index];
      var dragElemOffset = dragElems[index].getBoundingClientRect();
      var xcX = ev.clientX - dragElemOffset.left;
      var xcY = ev.clientY - dragElemOffset.top;

      // eslint-disable-next-line require-jsdoc
      function posIndex(left, top) {
        var row = Math.round(top / 106);
        var col = Math.round(left / 110);

        return row * vm.howColsInOneRow + col;
      }
      // eslint-disable-next-line require-jsdoc
      function mousemove(ev) {
        var left = ev.clientX - myApp.offsetLeft - xcX;
        var top = ev.clientY - myApp.offsetTop - xcY;

        if (left < 0) {
          left = 0;
        }
        if (top < 0) {
          top = 0;
        }
        if (left + 100 > myApp.clientWidth) {
          left = myApp.clientWidth - 100;
        }
        if (top + 96 > myApp.clientHeight) {
          top = myApp.clientHeight - 96;
        }

        dragItem.left = left;
        dragItem.top = top;
      }
      // eslint-disable-next-line require-jsdoc
      function mouseup() {
        var curPos = posIndex(dragItem.left, dragItem.top);

        if (curPos === index) {
          dragItem.left = vm.calcLeft(index);
          dragItem.top = vm.calcTop(index);
        } else {
          let showItems = vm.showItems;
          let swap = null;

          if (curPos > showItems.length - 1) {
            curPos = showItems.length - 1;
          }

          swap = showItems[index];
          showItems[index] = showItems[curPos];
          showItems[curPos] = swap;

          vm.adjust();
        }

        dragItem.zIndex = 0;
        document.removeEventListener("mousemove", mousemove);
        document.removeEventListener("mouseup", mouseup);
      }

      while (curElem) {
        if (curElem.tagName === "SPAN" && curElem.className === "remove") {
          isRemoveChild = true;
          break;
        } else {
          curElem = curElem.parentNode;
        }
      }

      if (!isRemoveChild) {
        dragItem.zIndex = 1;
        document.addEventListener("mousemove", mousemove);
        document.addEventListener("mouseup", mouseup);
      }
    },
    adjust() {
      const vm = this;
      const myApp = vm.$refs.myApp;

      this.howColsInOneRow = Math.floor(myApp.clientWidth / 110);

      this.showItems.forEach((item, index) => {
        item.top = this.calcTop(index);
        item.left = this.calcLeft(index);
      });
    }
  }
};
</script>

<style scoped lang="less">
.homeapp {
  padding: 10px;
}
.my-apps {
  .head {
    margin-bottom: 10px;
    .title {
      font-size: 14px;
      color: @primary;
      font-weight: 700;
    }
    .tip {
      font-size: 12px;
      color: @fColor3;
    }
  }
  .list {
    position: relative;
    .item {
      position: absolute;
      width: 100px;
      box-shadow: @shadow;
      text-align: center;
      padding-top: 16px;
      background-color: #fff;
      p {
        padding-top: 8px;
        padding-bottom: 10px;
        font-size: 12px;
        color: @fColor3;
      }
      .remove {
        position: absolute;
        right: 6px;
        top: 6px;
        width: 16px;
        height: 16px;
        border-radius: 50%;
        background-color: #ff0000;
        cursor: pointer;
        span {
          position: absolute;
          top: 7px;
          left: 4px;
          height: 2px;
          width: 8px;
          background-color: #fff;
        }
      }
    }
  }
}
.other-app {
  padding-top: 24px;
  .head {
    margin-bottom: 10px;
    .title {
      font-size: 14px;
      color: @primary;
      font-weight: 700;
    }
  }
  .list {
    .item {
      position: relative;
      float: left;
      width: 100px;
      text-align: center;
      box-shadow: @shadow;
      padding-top: 16px;
    }
    p {
      padding-top: 8px;
      padding-bottom: 10px;
      font-size: 12px;
      color: @fColor3;
    }
    .item + .item {
      margin-left: 10px;
    }
    .add {
      width: 16px;
      height: 16px;
      position: absolute;
      right: 6px;
      top: 6px;
      border-radius: 50%;
      background-color: #0088d7;
      cursor: pointer;
      .hor {
        position: absolute;
        width: 8px;
        height: 2px;
        left: 4px;
        top: 7px;
        background-color: #fff;
      }
      .ver {
        position: absolute;
        width: 2px;
        height: 8px;
        left: 7px;
        top: 4px;
        background-color: #fff;
      }
    }
  }
}
</style>
